home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr46 / stawin.zip / STAWIN.PRG next >
Text File  |  1993-06-09  |  6KB  |  206 lines

  1. /***
  2. * STAWIN.PRG by Jim Schaffner
  3. *
  4. * Displays a status bar across the screen when performing a long
  5. * running task, such as indexing or reporting.  This is a Clipper 5
  6. * version of the Foxpro STATWIN function, originally written by
  7. * Duane Keeling of Keeling Consulting.
  8. *
  9. * To use this, first call StatInit() with the desired top/left
  10. * coordinates of the display "window".  Coordinates are optional.
  11. * Then call StatWin() from within your processing loop, passing
  12. * the total to be processed, and the current process count.  There
  13. * are optional parameters for a display message, a logical for
  14. * displaying estimated completion time, a title, and colors.
  15. *
  16. * Here's an example:
  17. *
  18. * StatInit()
  19. * do while ! eof()
  20. *    StatWin(lastrec(),recno(),"Percent processed:",.t.)
  21. *    skip
  22. * enddo
  23. *
  24. * The StatWin() function will automatically call the cleanup routine
  25. * StatExit() when 100% has been reached, but a premature break from
  26. * the processing loop will cause this not to happen.  For this reason,
  27. * I have made the StatExit() function public rather than static, so
  28. * you can call it from outside this PRG to handle exceptions.  If you
  29. * fail to call StatExit(), you will get some strange display results
  30. * the next time you run StatWin().
  31. *
  32. * Here's an exception example:
  33. *
  34. * StatInit()
  35. * do while ! eof()
  36. *    StatWin(lastrec(),recno())
  37. *    if NAME = "SMITH"
  38. *       StatExit()
  39. *       exit
  40. *    endif
  41. *    skip
  42. * enddo
  43. *
  44. * Compile with /a/m/n.
  45. *
  46. * Enjoy!
  47. */
  48.  
  49. // "borrowed" from Clipper 5.2 COMMON.CH (allows compile in 5.01)
  50.  
  51. #xcommand DEFAULT <v1> TO <x1> [, <vn> TO <xn> ]                        ;
  52.           =>                                                            ;
  53.           IF <v1> == NIL ; <v1> := <x1> ; END                           ;
  54.           [; IF <vn> == NIL ; <vn> := <xn> ; END ]
  55.  
  56.  
  57. #include "setcurs.ch"
  58.  
  59. // Static variables:
  60.  
  61. //  ?Sav???         -> save video attributes, screen, etc.
  62. //  nTop ... nRight -> screen coordinates for display
  63. //  lFirst          -> denotes first pass through routine
  64.  
  65. STATIC cSavWin,cSavClr,nSavCsr
  66. STATIC nSavRow,nSavCol,lFirst := .t.
  67. STATIC nTop,nLeft,nBottom,nRight
  68.  
  69. /***
  70. * StatInit() - initialize the status display
  71. */
  72.  
  73. FUNCTION StatInit(nT,nL)
  74.  
  75.    nTop    := if(nT == NIL,0,nT)
  76.  
  77.    if nTop > maxrow()-6
  78.       nTop := maxrow()-6
  79.    endif
  80.  
  81.    nLeft   := if(nL == NIL,0,nL)
  82.  
  83.    if nLeft > maxcol()-53
  84.       nLeft := maxcol()-53
  85.    endif
  86.  
  87.    nBottom := nTop+5
  88.    nRight  := nLeft+52
  89.  
  90.    cSavWin := savescreen(nTop,nLeft,nBottom+1,nRight+1)
  91.  
  92.    cSavClr := setcolor()
  93.    nSavCsr := setcursor()
  94.    nSavRow := row()
  95.    nSavCol := col()
  96.  
  97.    setcursor(SC_NONE)
  98.  
  99. RETURN NIL
  100.  
  101. /***
  102. * StatWin() - display the status bar
  103. */
  104.  
  105. FUNCTION StatWin(nTotal,nCurrent,cMsg,lEstimate,cTitle,cColor)
  106.  
  107.    LOCAL nWidth,cFull,cHalf,nPct,nBlock,nBlocks,nEst,nCol
  108.  
  109.    STATIC nStart
  110.  
  111.    cFull  = chr(219) // █
  112.    cHalf  = chr(221) // ▌
  113.    nWidth = 50                      // default bar length to 50 characters
  114.  
  115.    setcolor("W+/BG,W+/BG")
  116.  
  117.    default cMsg to ""               // Default to NULL display message
  118.  
  119.    default lEstimate to .f.         // Default to NO estimating
  120.  
  121.    default cTitle to ""             // Default to NO window title
  122.  
  123.    default cColor to "W+/BG"        // default color to high white on cyan
  124.  
  125.    nPct := if(nTotal > 0,round((nCurrent*100)/nTotal,0),100)
  126.  
  127.    nPct := if(nPct > 100,100,nPct)  // This will prevent screen overrun and percentages > 100
  128.  
  129.    if lFirst
  130.       @ nTop,nLeft clear to nBottom,nRight
  131.       @ nTop,nLeft to nBottom,nRight
  132.  
  133.      // I have my own shadow routine, so I'll comment this out,
  134.      //  but take note if you want to include your own shadow.
  135.  
  136.      // Shadow(nTop,nLeft,nBottom,nRight)
  137.  
  138.       if lEstimate
  139.          nStart := seconds()
  140.          @ nTop+4,nLeft+01 say "Start: " + TimeAsString(nStart)
  141.          @ nTop+4,nLeft+22 say "Estimated Completion: "
  142.       endif
  143.       if ! empty(cMsg)                        // If we have a message then
  144.          @ nTop+1,nLeft+1 say padr(cMsg,48)   // display with padded spaces
  145.       endif
  146.       lFirst := .f.
  147.    else
  148.       if lEstimate
  149.          nEst := seconds() - nStart
  150.          nEst := (nEst*100)/nPct
  151.          @ nTop+4,nLeft+44 say TimeAsString(nStart+nEst+2)
  152.       endif
  153.    endif
  154.  
  155.    nBlock  := int(100/nWidth)
  156.  
  157.    nBlocks := int(nPct/nBlock)        // How many blocks do I need?
  158.  
  159.    nCol    := if(empty(cMsg),26,47)   // Calculate percentage display column
  160.  
  161.    @ nTop+1,nCol say str(nPct,3)+"%"       // Display percentage
  162.  
  163.    if nPct/2 # int(nPct/2)        // Add a half block if needed
  164.       @ nTop+02,nLeft+01 say replicate(cFull,nBlocks)+cHalf
  165.    else                           // and display the bar...
  166.       @ nTop+02,nLeft+01 say replicate(cFull,nBlocks)
  167.    endif
  168.  
  169.    if nCurrent >= nTotal              // If we're done (100%) then
  170.       inkey(1)                        // wait 1 second...
  171.       StatExit()                      // ...and clean up
  172.    endif
  173.  
  174. RETURN NIL
  175.  
  176.  
  177. // "borrowed" this one from Clipper sample source
  178.  
  179. /***
  180. *  TimeAsString( <nSeconds> ) --> cTime
  181. *  Convert numeric seconds to a time string
  182. *
  183. *  NOTE: Same as TSTRING() in Examplep.prg
  184. */
  185. STATIC FUNCTION TimeAsString( nSeconds )
  186.    RETURN StrZero(INT(Mod(nSeconds / 3600, 24)), 2, 0) + ":" +;
  187.           StrZero(INT(Mod(nSeconds / 60, 60)), 2, 0) + ":" +;
  188.           StrZero(INT(Mod(nSeconds, 60)), 2, 0)
  189.  
  190.  
  191. /***
  192. * StatExit() - exit from the status display & restore attributes
  193. */
  194.  
  195. FUNCTION StatExit()
  196.  
  197.    restscreen(nTop,nLeft,nBottom+1,nRight+1,cSavWin)
  198.  
  199.    setcolor(cSavClr)
  200.    setcursor(nSavCsr)
  201.    setpos(nSavRow,nSavCol)
  202.  
  203.    cSavWin := ""
  204.    lFirst  := .t.
  205.  
  206. RETURN NIL